#ifndef __COMMON_H__
#define __COMMON_H__
#pragma once

#ifdef _WIN32
#include "winsys.h"
#elif defined linux
#include "linux.h"
#endif

#include <string>
#include <vector>
#include <fstream>
#include "curl/curl.h"
#include "curl/easy.h"
#include "json/json.h"
#include "tinyxml/tinyxml.h"

#include <time.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif

#ifdef _WIN32
#ifdef _DLL_PRODUCT
#define DLL_PRODUCT_API __declspec(dllexport)
#else
#define DLL_PRODUCT_API __declspec(dllimport)
#endif
#elif defined linux
#define DLL_PRODUCT_API
#endif

#ifdef _WIN32
#ifdef _DLL_PUBLIC
#define DLL_PUBLIC_API __declspec(dllexport)
#else
#define DLL_PUBLIC_API __declspec(dllimport)
#endif
#elif defined linux
#define DLL_PUBLIC_API
#endif

#define MAX_DATA_SIZE 1024
#define HMAC_SHA1_OUT_LEN 21
#define ACCESSKEYID "kj39BpKarcBCa0J3"
#define ACCESSKEYSECRET "drbuuMbeZhmulKF8GSFAewWherQ3bX"

enum E_VALUE_TYPE
{
	E_VALUE_NONE = 0,
	E_VALUE_STRING,
	E_VALUE_LONG,
};

struct stBuffer
{
    uint32_t len;
    char data[MAX_DATA_SIZE];
};

extern DLL_PUBLIC_API stBuffer g_buf_tmp;

#ifdef _WIN32
DLL_PUBLIC_API int gettimeofday(struct timeval *tp, void *tzp);
#endif

DLL_PUBLIC_API int writer(void *data, uint32_t size, uint32_t nmemb, stBuffer *write_data);
DLL_PUBLIC_API bool curl_init(CURL **pconn, const char *url, stBuffer *p_buffer, const char *field = NULL, char *method = "GET");
DLL_PUBLIC_API bool send_curl(const char *url, const char *field = NULL, char *method = "GET");

DLL_PUBLIC_API void add_base_parameter(std::map<std::string, std::string> &mapCommonParameter, std::vector<std::string> &vecCommonParameter);
DLL_PUBLIC_API void quicksortHeadersByKey(std::vector<std::string> &v, int left, int right);
DLL_PUBLIC_API std::string urldecode(const std::string &str_source);
DLL_PUBLIC_API std::string urlencode(const std::string &str_source);
DLL_PUBLIC_API void parseMetaResponse(Json::Value &result, struct SResponseMap &responseMap);

struct SRequest
{
	std::string required;
	std::string tagName;
	std::string tagPosition;
	std::string type;
	std::string value;
	bool bIsSet;
};

struct SMember
{
	std::string tagName;
	std::string type;
	std::string value;
};

struct SResponseMap
{
	std::string tagName;
	std::string itemName;
	std::vector<struct SResponseMap*> vStructNode;
	std::vector<struct SResponseMap*> vArraysNode;
	std::vector<struct SMember> members;
};

#endif